package modbus

import (
	"sync"
)

// ByteSlicePool 字节切片对象池
type ByteSlicePool struct {
	pool *sync.Pool
}

// Uint16SlicePool uint16切片对象池
type Uint16SlicePool struct {
	pool *sync.Pool
}

var (
	// 全局字节切片池
	byteSlicePool = &ByteSlicePool{
		pool: &sync.Pool{
			New: func() interface{} {
				return make([]byte, 0, 256) // 预分配256字节容量
			},
		},
	}

	// 全局uint16切片池
	uint16SlicePool = &Uint16SlicePool{
		pool: &sync.Pool{
			New: func() interface{} {
				return make([]uint16, 0, 128) // 预分配128个uint16容量
			},
		},
	}
)

// GetByteSlice 从池中获取字节切片
func (p *ByteSlicePool) GetByteSlice(minCap int) []byte {
	slice := p.pool.Get().([]byte)
	slice = slice[:0] // 重置长度但保留容量

	// 如果容量不足，创建新的切片
	if cap(slice) < minCap {
		return make([]byte, 0, minCap)
	}
	return slice
}

// PutByteSlice 返回字节切片到池中
func (p *ByteSlicePool) PutByteSlice(slice []byte) {
	// 只有合理大小的切片才放回池中，避免内存泄漏
	if cap(slice) <= 4096 {
		p.pool.Put(slice)
	}
}

// GetUint16Slice 从池中获取uint16切片
func (p *Uint16SlicePool) GetUint16Slice(minCap int) []uint16 {
	slice := p.pool.Get().([]uint16)
	slice = slice[:0] // 重置长度但保留容量

	// 如果容量不足，创建新的切片
	if cap(slice) < minCap {
		return make([]uint16, 0, minCap)
	}
	return slice
}

// PutUint16Slice 返回uint16切片到池中
func (p *Uint16SlicePool) PutUint16Slice(slice []uint16) {
	// 只有合理大小的切片才放回池中，避免内存泄漏
	if cap(slice) <= 2048 {
		p.pool.Put(slice)
	}
}

// 便利函数，供内部使用

// getByteSlice 获取字节切片（内部使用）
func getByteSlice(minCap int) []byte {
	return byteSlicePool.GetByteSlice(minCap)
}

// putByteSlice 返回字节切片（内部使用）
func putByteSlice(slice []byte) {
	byteSlicePool.PutByteSlice(slice)
}

// getUint16Slice 获取uint16切片（内部使用）
func getUint16Slice(minCap int) []uint16 {
	return uint16SlicePool.GetUint16Slice(minCap)
}

// putUint16Slice 返回uint16切片（内部使用）
func putUint16Slice(slice []uint16) {
	uint16SlicePool.PutUint16Slice(slice)
}
